// 图片验证码识别


// 临时图片元素
// 创建一个新的img元素
// var img = document.createElement('img');
// img.src = '//local.bs.ht.dev.norincogroup-ebuy.com/tempimg/7.jpg';
// img.alt = '临时图片';
// img.width = 100;
// img.height = 26;
// img.style.float = 'left';
// document.body.appendChild(img);
// const imgElement = img;

let imgElementDom = document.getElementById('img_rand_code');
let valueInput = document.getElementById('randCode');
const dev = window.location.hostname.toLowerCase().indexOf('norincogroup-ebuy.com') > -1;
const local = window.location.hostname.toLowerCase().startsWith("local") ;

function imageCode(){
  if(!imgElementDom || !valueInput){
    imgElementDom = document.getElementsByClassName("authimg")[0]
    valueInput = document.querySelector("input[class='yj-input__inner'][placeholder='验证码']");
    if(!imgElementDom || !valueInput){
        return;
    }
  }

  // if (!isElementVisible(imgElement)) {
  //     return ;
  // }

  // if(imgElementDom.width != 100 || imgElementDom.height != 26){
  //   // getImageDimensions();
  //   imgElementDom.width = 100;
  //   imgElementDom.height = 26;
  //   // return;
  // }

  exec(imgElementDom);
}

function exec(imgElement){
    let height = 26;
    let width = 100;

    // 基础/色彩过滤 图像画布
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // canvas.width = imgElement.width;
    // canvas.height = imgElement.height;

    canvas.width = width;
    canvas.height = height;

    // canvas.id = 'stepFinalImg';
    // const existFinalDom = document.getElementById('stepFinalImg');
    // if(existFinalDom){
    //     existFinalDom.remove();
    // }

    // 将图片绘制到canvas上
    ctx.drawImage(imgElement, 0, 0);

    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    
    // 二值化图像数据 并展示
    let imgData = toHex(imageData, canvas.width, canvas.height);
    ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空Canvas
    ctx.putImageData(imgData, 0, 0, 0, 0, canvas.width, canvas.height); // 画出二值化图
    
    // canvas.id = 'stepThreeCtx';
    // canvas.style.float = 'left';
    // const threddDom = document.getElementById('stepThreeCtx');
    // if(threddDom){
    //     threddDom.remove();
    // }
    // document.body.appendChild(canvas);

    // 分割的次数
    const numSplits = 4;
    // 分割环境参数选择
    let splitStartArray = null;
    let operatekeys = null;
    let numkeys = null;
    // 根据环境取不同的特征码
    if(local){
        splitStartArray = splitStartArray_local;
        operatekeys = operatekeys_local;
        numkeys = numkeys_local;
    }else if(dev){
      splitStartArray = splitStartArray_dev;
      operatekeys = operatekeys_dev;
      numkeys = numkeys_dev;
    } else{
      numkeys = numkeys_test;
      operatekeys = operatekeys_test;
      splitStartArray = splitStartArray_test;
    }

    // 遍历输出KEY的图像
    // showKeyConsole(numkeys);

    // 操作数字及符号
    let num1 = '';
    let num2 = '';
    let opt = '';

    // 分割图片根据特征码取值
    for (let i = 0; i < numSplits; i++) {
        // 计算当前分割的起始位置
        const startX = splitStartArray[i][0];
        // 计算当前分割的宽度
        const sliceWidth = splitStartArray[i][1] - splitStartArray[i][0];

        // 创建一个新的canvas用于存储当前分割的图片
        const sliceCanvas = document.createElement('canvas');
        const sliceCtx = sliceCanvas.getContext('2d');

        // 从原始canvas中分割出当前的图片部分
        let drowHeight = height;
        let startY = 1;
        let y = height-2;
        if(local){
          drowHeight = 18;
          startY = 7;
          y = drowHeight;
          sliceCanvas.width = sliceWidth;
          sliceCanvas.height = y;
        }else if(dev){
          drowHeight = 17;
          startY = 7;
          y = drowHeight;
          sliceCanvas.width = sliceWidth;
          sliceCanvas.height = y;
        }else{
          drowHeight = 18;
          startY = 6;
          y = drowHeight;
          sliceCanvas.width = sliceWidth;
          sliceCanvas.height = y;
        }
        sliceCtx.drawImage(canvas, startX, startY, sliceWidth, y, 0, 0, sliceWidth, drowHeight);
        
        // 获取canvas上的像素数据
        const imageData = sliceCtx.getImageData(0, 0, sliceCanvas.width, sliceCanvas.height);
        var pixelArray = toXY(imageData, sliceCanvas.width, sliceCanvas.height); // 将图片数据转化为数组
        
        // 腐蚀
        // pixelArray = corrode(pixelArray); 
        // console.log('腐蚀：')
        // let graphic = binaryArrayToGraphic(pixelArray);
        // console.log(graphic);
        
        // 膨胀
        // pixelArray = expand(pixelArray); 
        // console.log('膨胀:')
        // console.log(pixelArray);
        let graphic = binaryArrayToGraphic(pixelArray);
        // console.log(graphic);

        let codeAttr = getCode(pixelArray);
        // console.log('位置：', i,'特征码：', codeAttr);
        let rv = readNum(codeAttr, (i==1 ? operatekeys : numkeys));

        if(i == 0){
            num1 = rv;
        }else if(i == 1){
            opt = rv;
        }else{
            if(rv != ''){
                num2 += rv;
            }
        }

        // 将分割后的图片转换为Data URL 并展示
        // showSplitImg(i, sliceCanvas);
    }

    // 计算结果输出
    console.log('表达式：', num1, opt, ' ? = ', num2);
    let calcValue = '';
    if('+' == opt){
        calcValue = num2 - num1;
    }else{
        calcValue = num2 / num1;
    }
    console.log('计算值：', calcValue);
    if(isPositiveIntegerLessThan10(calcValue)){
        valueInput.value = calcValue;
        changeReactInputValue(valueInput, calcValue);
    }else{
      // 省略末位计算输出
      // 将数值转换为字符串
      let numberString = num2.toString();
      let onesPlace = parseInt(numberString[0], 10);
      if('+' == opt){
        calcValue = onesPlace - num1;
      }else{
        calcValue = onesPlace / num1;
      }
      if(isPositiveIntegerLessThan10(calcValue)){
        valueInput.value = calcValue;
        changeReactInputValue(valueInput, calcValue);
      }else{
        valueInput.value = '';
        changeReactInputValue(valueInput, '');
      }
    }
}

//调用下面这个函数可以给框架包装过的input框赋值
function changeReactInputValue(inputDom,newText){
    let lastValue = inputDom.value;
    inputDom.value = newText;
    let event = new Event('input', { bubbles: true });
    event.simulated = true;
    let tracker = inputDom._valueTracker;
    if (tracker) {
      tracker.setValue(lastValue);
    }
    inputDom.dispatchEvent(event);
}


// 显示分割后的图像
function showSplitImg(i, sliceCanvas){
  let dom_img = 'pic_img_' + i;
  const existDom = document.getElementById(dom_img);
  if(existDom){
      existDom.remove();
  }
  const dataURL = sliceCanvas.toDataURL();
  const newImg = document.createElement('img');
  newImg.src = dataURL;
  newImg.id = dom_img;
  newImg.style.marginLeft = '2px';
  newImg.style.float = 'left';
  document.body.appendChild(newImg);
}

// 二值化图像
function toHex(fromImgData, WIDTH, HEIGHT){
    var fromPixelData = fromImgData.data;
    var greyAve = 0;
    for(var j=0;j<WIDTH*HEIGHT;j++){
        var r = fromPixelData[4*j];
        var g = fromPixelData[4*j+1];
        var b = fromPixelData[4*j+2];
        greyAve += r*0.3 + g*0.59 + b*0.11;
    }
    greyAve /= WIDTH*HEIGHT;//计算平均灰度值。
    for(j=0;j<WIDTH*HEIGHT;j++){
        r = fromPixelData[4*j];
        g = fromPixelData[4*j+1];
        b = fromPixelData[4*j+2];
        var grey = r*0.333 + g*0.333 + b*0.333;//取平均值。
        grey = grey>greyAve?255:0;
        fromPixelData[4*j] = grey;
        fromPixelData[4*j+1] = grey;
        fromPixelData[4*j+2] = grey;
    }
    return fromImgData;
}

// 图像转数组
function toXY(fromImgData, WIDTH, HEIGHT){
    var result = new Array(HEIGHT);
    var fromPixelData = fromImgData.data;
    for(var j=0;j<HEIGHT;j++){
        result[j] = new Array(WIDTH);
        for(var k=0;k<WIDTH;k++){
            var r = fromPixelData[4*(j*WIDTH+k)];
            var g = fromPixelData[4*(j*WIDTH+k)+1];
            var b = fromPixelData[4*(j*WIDTH+k)+2];
            // let f = fromPixelData[4*(j*WIDTH+k)+3];

            // result[j][k] = r > 128 ? 0 : 1;
            result[j][k] = (r+g+b)>500?0:1;//赋值0、1给内部数组
        }
    }
    return result;
}

// 腐蚀（简单）
function corrode(fromArray){
    for(var j=1;j<fromArray.length-1;j++){
        for(var k=1;k<fromArray[j].length-1;k++){
            if(fromArray[j][k]==1&&fromArray[j-1][k]+fromArray[j+1][k]+fromArray[j][k-1]+fromArray[j][k+1]==0){
                fromArray[j][k] = 0;
            }
        }
    }
    return fromArray;
}

// 膨胀（简单）
function expand(fromArray){
    for(var j=1;j<fromArray.length-1;j++){
        for(var k=1;k<fromArray[j].length-1;k++){
            if(fromArray[j][k]==0&&fromArray[j-1][k]+fromArray[j+1][k]+fromArray[j][k-1]+fromArray[j][k+1]==4){
                fromArray[j][k] = 1;
            }
        }
    }
    return fromArray;
}

// 数组转图像
function fromXY(ctx1, fromArray, WIDTH, HEIGHT){
    var fromImgData = ctx1.createImageData(WIDTH,HEIGHT);
    var fromPixelData = fromImgData.data;
    for(var j=0;j<fromArray.length;j++){
        for(var k=0;k<fromArray[j].length;k++){
            var innergrey = (fromArray[j][k]==1?0:255);
            fromPixelData[4*(j*WIDTH+k)] = innergrey;
            fromPixelData[4*(j*WIDTH+k)+1] = innergrey;
            fromPixelData[4*(j*WIDTH+k)+2] = innergrey;
            fromPixelData[4*(j*WIDTH+k)+3] = 255;
        }
    }
    return fromImgData;
}

// 尺寸归一化
function zoomToFit(fromArray, WIDTH, HEIGHT){
    var imgD = fromXY(fromArray, WIDTH, HEIGHT);
    var w = lastWidth;
    var h = lastHeight;
    var tempc1 = document.createElement("canvas");
    var tempc2 = document.createElement("canvas");
    tempc1.width = fromArray[0].length;
    tempc1.height = fromArray.length;
    tempc2.width = w;
    tempc2.height = h;
    var tempt1 = tempc1.getContext("2d");
    var tempt2 = tempc2.getContext("2d");
    tempt1.putImageData(imgD,0,0,0,0,tempc1.width,tempc1.height);
    tempt2.drawImage(tempc1,0,0,w,h);
    var returnImageD = tempt2.getImageData(0,0,WIDTH,HEIGHT);
    fromArray = toXY(returnImageD, WIDTH, HEIGHT);
    fromArray.length = h;
    for(var i=0;i<h;i++){
        fromArray[i].length = w;
    }
    return fromArray;
}

// 生成特征码
function getCode(fromArray){
    var result = '';
    for(var j=0;j<fromArray.length;j++){
        for(var k=0;k<fromArray[j].length;k++){
            result += (""+fromArray[j][k]);
        }
        result += ";";
    }
    return result;
}

// 匹配特征码读取值
function readNum(str, keys){
    var tempSimilar = 0;
    var tempFeature = '';
    var tempNum = 0;
    let infoNum = countOnes(str);
    str = str.split('');
    for(var i=0;i<keys.length;i++){
        var thisFeature = keys[i][1]; // 特征码
        var thisNum = keys[i][0]; // 特征码对应值
        var thisSimilar = 0; // 相似度
        thisFeature = thisFeature.split('');
        for(var j=0;j<thisFeature.length;j++){
            if(thisFeature[j]==str[j]){
                thisSimilar++;
            }
        }

        // 归一化匹配度值
        if(thisNum != '+' && thisNum != '*'){
          if(infoNum < 20){
            thisSimilar = 0;
          }
        }

        if(thisSimilar>tempSimilar){
            tempFeature = thisFeature;
            tempNum = thisNum;
            tempSimilar = thisSimilar;
        }
    }
    // console.log(tempNum, ' 特征匹配度 ', tempSimilar);
    return tempNum;
}

// 检查数值是否为正整数且小于10
function isPositiveIntegerLessThan10(num) {
    return Number.isInteger(num) && num >= 0 && num < 10;
}

function isElementVisible(element) {
    if (!(element instanceof HTMLElement)) {
        throw new Error('The provided element is not a valid HTML element.');
    }

    // 检查元素的display和visibility属性
    if (element.style.display === 'none' || element.style.visibility === 'hidden') {
        return false;
    }

    // 检查元素的宽度和高度
    if (element.offsetWidth <= 0 || element.offsetHeight <= 0) {
        return false;
    }

    // 检查元素的滚动位置
    const rect = element.getBoundingClientRect();
    if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= window.innerWidth || rect.top >= window.innerHeight) {
        return false;
    }

    // 检查父元素的display和visibility属性
    let parentElement = element.parentElement;
    while (parentElement) {
        if (window.getComputedStyle(parentElement).display === 'none' || window.getComputedStyle(parentElement).visibility === 'hidden') {
            return false;
        }
        parentElement = parentElement.parentElement;
    }

    return true;
}

// 输出二维图形
function binaryArrayToGraphic(array, pixelChar = '██', spaceChar = '  ') {
    let graphic = '';
    for (let row of array) {
        for (let cell of row) {
            graphic += (cell == 1) ? pixelChar : spaceChar;
        }
        graphic += '\n'; // 换行符，用于控制台展示
    }
    return graphic;
}

function showKeyConsole(numArray){
  for(let j = 0 ; j< numArray.length; j++){
    // 使用分号分隔字符串，得到一个字符串数组
    var rows = numArray[j][1].split(';');
    // 创建一个空数组，用于存储二维数组
    var twoDimensionalArray = [];
    // 遍历字符串数组，将每个字符串转换为字符数组，并添加到二维数组中
    for (var i = 0; i < rows.length; i++) {
      twoDimensionalArray.push(rows[i].split(''));
    }
    console.log('key:', numArray[j][0]);
    console.log(binaryArrayToGraphic(twoDimensionalArray));
  }

}

function countOnes(str) {
  let count = 0;
  for (let i = 0; i < str.length; i++) {
      if (str[i] === '1') {
          count++;
      }
  }
  return count;
}

function getImageDimensions() {
  // 创建一个新的Image对象
  var img = new Image();

  // 设置Image对象的src属性为img元素的src属性
  img.src = imgElementDom.src;

  // 当图像加载完成时，返回其宽度和高度
  img.onload = function() {
      exec(img);
      // return {
      //     width: img.width,
      //     height: img.height
      // };
  };

  // 如果图像加载失败，返回null
  img.onerror = function() {
      // return null;
  };
}

imageCode();
setTimeout(function(){
  imageCode();
}, 800);


if(imgElementDom){
  imgElementDom.addEventListener('load', function() {
        imageCode();
    });
}


// document.getElementById('img_rand_code').addEventListener('click', function(){imageCode()});